package com.hd.hdxgddcommon.utils;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.hd.hdxgddcommon.annotation.select.SelectVoAnno;
import com.hd.hdxgddcommon.annotation.select.SelectVoField;
import com.hd.hdxgddcommon.constant.SelectVoConstant;
import com.hd.hdxgddcommon.entity.vo.SelectVo;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Created by Administrator on 2019/4/15.
 */
public class EntityCopyUtils {

    public static <T> IPage<T> copy(IPage page, Class<T> clazz) {
        if (page == null) return null;
        List records = page.getRecords();
        List<T> newList = copy(records, clazz);
        page.setRecords(newList);
        return page;
    }

    public static <T> List copy(List records, Class<T> clazz) {
        List<T> newList = new ArrayList<>();
        for (Object t : records) {
            T copy = copy(t, clazz);
            if (copy != null)
                newList.add(copy);
        }
        return newList;
    }

    public static <T> T copy(Object src, Class<T> clazz) {

        if (src == null) {
            return null;
        }
        T t;
        try {
            t = clazz.newInstance();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        Class<?> srcClass = src.getClass();
        Field[] declaredFields = srcClass.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            try {
                Object o = field.get(src);
                Field declaredField = clazz.getDeclaredField(field.getName());
                declaredField.setAccessible(true);
                declaredField.set(t, o);
            } catch (Exception e) {
                continue;
            }
        }
        return t;

    }


    //    public static SelectVo tran(Object o) {
//        Class<?> clazz = o.getClass();
//        Field[] fields = clazz.getDeclaredFields();
//        String label = null;
//        String value = null;
//        for (Field field : fields) {
//            field.setAccessible(true);
//            SelectVoAnno annotation = field.getAnnotation(SelectVoAnno.class);
//            if (annotation != null) {
//                try {
//                    int fileType = annotation.fileType();
//                    if (fileType == SelectVoConstant.TYPE.LABEL) {
//                        Object oid = field.get(o);
//                        if (oid != null) label = String.valueOf(oid);
//                    } else if (fileType == SelectVoConstant.TYPE.VALUE) {
//                        Object oname = field.get(o);
//                        if (oname != null) value = String.valueOf(oname);
//                    }
//                } catch (Exception e) {
//                    e.printStackTrace();
//                }
//            }
//        }
//        return new SelectVo(label, value);
//    }
//    public static List<SelectVo> tran(List list) {
//
//        List<SelectVo> selectVos = new ArrayList<>();
//        for (Object o : list) {
//            selectVos.add(tran(o));
//        }
//        return selectVos;
//    }
    public static <T> List<SelectVo> tran(List<T> list) {
        if (list.size() == 0) return Collections.EMPTY_LIST;
        else {
            T t = list.get(0);
            Class<?> clazz = t.getClass();
            SelectVoField field = findField(clazz);
            Field label = field.getLabel();
            Field value = field.getValue();
            List<SelectVo> selectVos = new ArrayList<>();
            for (Object o : list) {
                selectVos.add(tran(o, label, value));
            }
            return selectVos;
        }
    }

    public static SelectVo tran(Object o) {
        Class<?> clazz = o.getClass();
        SelectVoField field = findField(clazz);
        Field label = field.getLabel();
        Field value = field.getValue();
        if (label == null || value == null) return null;
        return tran(o, label, value);
    }

    public static SelectVo tran(Object o, Field label, Field value) {
        if (label == null || value == null) throw new NullPointerException();
        String labelString = null;
        String valueString = null;
        try {
            label.setAccessible(true);
            value.setAccessible(true);
            Object labelObj = label.get(o);
            if (labelObj != null) labelString = String.valueOf(labelObj);
            Object valueObj = value.get(o);
            if (valueObj != null) valueString = String.valueOf(valueObj);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return new SelectVo(labelString, valueString);
    }

    public static SelectVoField findField(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        Field label = null;
        Field value = null;
        for (Field field : fields) {
            SelectVoAnno annotation = field.getAnnotation(SelectVoAnno.class);
            if (annotation != null) {
                try {
                    int type = annotation.type();
                    if (type == SelectVoConstant.TYPE.LABEL) {
                        label = field;
                    } else if (type == SelectVoConstant.TYPE.VALUE) {
                        value = field;
                    }
                    if (label != null && value != null) break;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return new SelectVoField(label, value);
    }
}
